﻿using System;
using System.IO;
using Microsoft.SharePoint;

namespace Lapointe.WebPartPageHistory.ListEventReceivers
{
    internal class HistoryHelper
    {
        private const string PROP_HISTORY_METHOD_KEY = "HistoryMethod";
        public const string PROP_VERSIONID_KEY = "VersionID";
        public const string LIST_WEBPARTHISTORY_URLNAME = "WebPartPageHistoryList";
        public const string PROP_INCLUDE_DEPENDENCIES_KEY = "IncludeDependencies";

        /// <summary>
        /// Gets the history method.
        /// </summary>
        /// <param name="list">The list.</param>
        /// <returns></returns>
        internal static HistoryMethod GetHistoryMethod(SPList list)
        {
            // Get the history method from the list settings (we use the root folder item to store list settings).
            HistoryMethod method = HistoryMethod.OTB;
            if (list.RootFolder.Properties[PROP_HISTORY_METHOD_KEY] != null && list.RootFolder.Properties[PROP_HISTORY_METHOD_KEY].ToString() != string.Empty)
                method = (HistoryMethod)Enum.Parse(typeof(HistoryMethod), list.RootFolder.Properties[PROP_HISTORY_METHOD_KEY].ToString(), true);
            return method;
        }


        /// <summary>
        /// Gets the includes dependencies settings for the list.
        /// </summary>
        /// <param name="list">The list.</param>
        /// <returns></returns>
        internal static bool IncludeDependencies(SPList list)
        {
            // Get the dependency setting from the list settings (we use the root folder item to store list settings).
            bool includeDependencies = false;
            if (list.RootFolder.Properties[PROP_INCLUDE_DEPENDENCIES_KEY] != null && list.RootFolder.Properties[PROP_INCLUDE_DEPENDENCIES_KEY].ToString() != string.Empty)
                includeDependencies = bool.Parse(list.RootFolder.Properties[PROP_INCLUDE_DEPENDENCIES_KEY].ToString());
            return includeDependencies;
        }

        /// <summary>
        /// Gets the history method.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        internal static HistoryMethod GetHistoryMethod(SPListItem item)
        {
            HistoryMethod method = HistoryMethod.OTB;
            if (item.Properties[PROP_HISTORY_METHOD_KEY] != null && item.Properties[PROP_HISTORY_METHOD_KEY].ToString() != string.Empty)
                method = (HistoryMethod)Enum.Parse(typeof(HistoryMethod), item.Properties[PROP_HISTORY_METHOD_KEY].ToString(), true);
            return method;
        }

        /// <summary>
        /// Sets the history method.
        /// </summary>
        /// <param name="list">The list.</param>
        /// <param name="method">The method.</param>
        internal static void SetHistoryMethod(SPList list, HistoryMethod method)
        {
            SPFolder item = list.RootFolder;
            item.Properties[PROP_HISTORY_METHOD_KEY] = method.ToString();
            item.Update();
        }

        /// <summary>
        /// Gets the temp directory used to store the exported files.
        /// </summary>
        /// <returns></returns>
        internal static string GetTempDirectory()
        {
            return Path.Combine(Path.GetTempPath(), "WebPartPageHistory\\" + Guid.NewGuid());
        }

        /// <summary>
        /// Adds the exported item which must be packaged as a zip file to the history list.
        /// </summary>
        /// <param name="sourceItem">The source item.</param>
        /// <param name="method">The method that was used to export the item.</param>
        /// <param name="zipFile">The zip file containing the exported item.</param>
        /// <param name="siteId">The site ID.</param>
        /// <param name="relativeWebUrl">The relative web URL.</param>
        internal static void AddHistoryItem(SPListItem sourceItem, HistoryMethod method, string zipFile, Guid siteId, string relativeWebUrl)
        {
            using (SPSite site = new SPSite(siteId))
            using (SPWeb web = site.OpenWeb(relativeWebUrl))
            {
                SPDocumentLibrary historyList = (SPDocumentLibrary)CommonUtilities.GetListByUrl(web, LIST_WEBPARTHISTORY_URLNAME);
                SPFolder folder = CommonUtilities.GetFolder(web, historyList, sourceItem.ParentList.ID + "/" + sourceItem.ID);
                SPFile file = folder.Files.Add(folder.ServerRelativeUrl + "/" + sourceItem.Properties[PROP_VERSIONID_KEY] + ".zip",
                                               File.ReadAllBytes(zipFile));
                file.Item.Properties[PROP_HISTORY_METHOD_KEY] = method.ToString();
                file.Item.SystemUpdate(false);
            }
        }


        /// <summary>
        /// Gets the exported item object.
        /// </summary>
        /// <param name="siteId">The site ID.</param>
        /// <param name="relativeWebUrl">The relative web URL.</param>
        /// <param name="sourceItem">The source item which to which we are trying to retrieve the history of.</param>
        /// <param name="restoreKey">The restore key used to determine which version to retrieve.</param>
        /// <returns>The SPListItem object containing the zip file that can be used to import (restore) the item.</returns>
        internal static SPListItem GetHistoryItem(Guid siteId, string relativeWebUrl, SPListItem sourceItem, string restoreKey)
        {
            SPListItem historyItem = null;
            using (SPSite site = new SPSite(siteId))
            using (SPWeb web = site.OpenWeb(relativeWebUrl))
            {
                SPDocumentLibrary historyList =
                    (SPDocumentLibrary)CommonUtilities.GetListByUrl(web, LIST_WEBPARTHISTORY_URLNAME);

                try
                {
                    historyItem = (SPListItem)web.GetObject(site.MakeFullUrl(historyList.RootFolder.ServerRelativeUrl) + "/" +
                                                            sourceItem.ParentList.ID + "/" +
                                                            sourceItem.ID + "/" + restoreKey + ".zip");
                }
                catch (FileNotFoundException)
                {
                }
            }
            return historyItem;
        }
    }
}
